Time field
canonInput that parses typed times with a list of quarter-hour options.
acrm !4087 (28 Sep 2026, owner): the visible duration next to times uses `fmtDurShort` — „45 m“ · „1 h“ · „1 h 30 m“ (in the context of time „m“ = minutes). Screen readers keep the full „min“ via `fmtDur` (TimeField option aria-label, DateTimeRange hidden live text) so „m“ is not read as metres. Other durations in the app (timeline, Setkání, tasks, reminders) keep „min“.
Used in 9 files · 7 areas · 15× — components/assistant, components/callwrapup, components/mail, components/meetings, components/tasks, components/timeline …
The time input of the design system. React <TimeField> (packages/ui/src/components/TimeField.tsx) emits .dp-field.time and, when open, the list .dp-timelist / .dp-topt inside a Picker panel. It replaces native <input type="time">: the value can be typed ("930", "9:30", "půl 10", "čtvrt na 10") and the list is a quick pick, not the only path.
When to use
- A single time of day: task time ("Přidat čas" in the task dialog), attendance stamp.
- The "od" and "do" ends of an event; the "do" end gets
getStartso it offers only times after the start, shows the duration next to each option and accepts a duration ("+30", "+1h", "1,5h", "90m"). - A coarser list where quarter hours are noise:
step={30}(the typed value still takes any minute).
When not to use
- Date and time of an event together — use Date-time range, which composes two Time fields with a Date field.
- Duration alone (minutes) — a numeric input; Time field is a clock time.
- A native
<input type="time">anywhere in the app (canon since 21 Aug 2026).
Anatomy
- Anchor
.dp-anchoraround the field; the panel is portalled and positioned to it. - Field
.dp-field.time: 88×32px, same border, radius and focus ring as Date field; no trigger icon — the list opens with ↓ or after typing. - Input
.dp-input:400 13px var(--font-sans), placeholder "–", value shown asfmtHminh23("9:30", "14:00"). - List
.dp-timelist: width 132px, max height 264px,role="listbox"; options.dp-topt30px rows,500 13px,.on=--accent-ink600 (selected has no fill); duration column.din--overline--fg-mutedwhengetStartis set. - States: focus-within ring,
.disabled(--surface-75,--border, muted text). There is no error state; an unparsable text reverts to the last value on blur. - Value contract: minutes from midnight (0–1440) or
null; convert toHH:mmfor the API.
Best practices
- Pair "od" and "do" in
.dp-timegroupwith.dp-sep"–" and give the end fieldgetStart. - Keep
step={15}by default; use 30 only where the schedule is coarse (room booking). - Wrap a standalone time in
<Field label="Čas">or the panel row.dp-timerowwith the clock icon.
- A select with 96 options or a spinner instead of this field.
- Widening the field to the form column — 88px is the content width of "23:45".
- Filling the list with the duration column when there is no start (
getStartonly on the end field).
Content
- Times in 24-hour
h:mmwith no leading zero ("9:30", "14:00"); durations byfmtDur("45 min", "1 h", "1 h 30 min"). - Placeholder "–" — the field is small, no words fit.
ariaLabeldefault "Čas"; use "Od" / "Do" for the two ends.- Parser notes (not rendered by the field, available from
parseTimeInput): "Nerozumím — zkus 9:30, 930 nebo „půl 10“", "Hodina je 0–23", "Minuta je 0–59", "Délka musí být kladná".
Related
- date-field — the date part next to it.
- date-time-range — the canonical composition for events.
- picker-panel — hosts the time list.
Input rule — approved exception (owner, 1. 10. 2026, acrm !4331)
The binding rule „structured value = mask, never free text“ applies with one approved exception: TimeField accepts a closed vocabulary instead of a fixed separator mask, because people type and say time in several forms. Conditions (all mandatory):
- Template visible: placeholder
hh:mm(in the Do fieldhh:mm nebo +30). - Only characters that can form a valid entry are accepted while typing: digits,
:.,space,+, and the words půl / čtvrt / tři čtvrtě / na / h / m / min. Anything else (@,#,/, other letters) is refused on input. - Accepted forms (all = 9:05):
9:5,0905,905,9:05,9.05,9,05;9= 9:00;půl 10,čtvrt na 10. In the Do field also a duration:+30,1,5h,90m. A comma is a dot except inside a duration with a unit. - Range errors show immediately while typing, under the field in
--critical-inkwitharia-invalid+aria-describedby(Hodina je 0–23,Minuta je 0–59). „Nerozumím…“ only after leaving the field; the text and the error stay, nothing is reverted silently. - Only a complete valid value is saved; after leaving the field it is shown normalised (
9:05). - Contract test covers the accepted and refused forms (19 cases).
Source: docs/date-time/time-field.usage.md · GitLab